package org.itboys.seller.service;

import org.apache.commons.collections.CollectionUtils;
import org.itboys.seller.constant.CaliforniaSiteConstant;
import org.itboys.seller.mapper.InfoPublishMapper;
import org.itboys.seller.meta.InfoPublish;
import org.itboys.seller.meta.InfoPublishExample;
import org.itboys.seller.utils.MatchingUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author hzliangchong1@corp.netease.com
 *         Date 2016/10/23.
 */
@Service
public class InfoPublishService {

    private static final Logger logger = LoggerFactory.getLogger(MatchInfoService.class);

    @Resource
    private InfoPublishMapper infoPublishMapper;
    @Resource
    private MatchInfoService matchInfoService;
    @Resource
    private CaliforniaSiteUserService californiaSiteUserService;

    public void insert(InfoPublish infoPublish) {
        infoPublishMapper.insert(infoPublish);
    }

    public boolean canProvideHelp(String accountId) {
        InfoPublishExample example = new InfoPublishExample();
        example.createCriteria().andAccountIdEqualTo(accountId)
                .andHelpTypeEqualTo(CaliforniaSiteConstant.HelpType.PROVIDER)
                .andStateNotEqualTo(CaliforniaSiteConstant.InfoState.CONFIRM);
        return infoPublishMapper.selectByExample(example).size() == 0;
    }

    public boolean canAcceptHelp(String accountId) {
        InfoPublishExample example = new InfoPublishExample();
        example.createCriteria().andAccountIdEqualTo(accountId)
                .andHelpTypeEqualTo(CaliforniaSiteConstant.HelpType.PROVIDER)
                .andStateNotEqualTo(CaliforniaSiteConstant.InfoState.CONFIRM);
        return infoPublishMapper.selectByExample(example).size() == 0;
    }

    public List<InfoPublish> queryInfo(String accountId, int offset, int limit) {
        InfoPublishExample example = new InfoPublishExample();
        example.createCriteria().andAccountIdEqualTo(accountId);
        example.setLimitStart(offset);
        example.setLimitEnd(limit);
        example.setOrderByClause("state");
        return infoPublishMapper.selectByExample(example);
    }

    public long totalInfo(String accountId) {
        InfoPublishExample example = new InfoPublishExample();
        example.createCriteria().andAccountIdEqualTo(accountId);
        return infoPublishMapper.countByExample(example);
    }

    public List<InfoPublish> getAllNunMatchRecords(Integer helpType) {
        InfoPublishExample example = new InfoPublishExample();
        InfoPublishExample.Criteria criteria = example.createCriteria();
        if (helpType != null) {
            criteria.andHelpTypeEqualTo(helpType);
            if (helpType == CaliforniaSiteConstant.HelpType.ACCEPT) {
                example.setOrderByClause("create_time");
            } else {
                example.setOrderByClause("amount");
            }
        } else {
            example.setOrderByClause("create_time");
        }
        criteria.andStateEqualTo(CaliforniaSiteConstant.InfoState.PUBLISH)
        .andCreateTimeWapGreaterThan(System.currentTimeMillis(), 5 * 60 * 1000L);
        //TODO 正式上线后这里要改成24小时
        return infoPublishMapper.selectByExample(example);
    }

    public void startMatch() {
        List<InfoPublish> acceptHelpList = getAllNunMatchRecords(CaliforniaSiteConstant.HelpType.ACCEPT);
        List<InfoPublish> provideHelpList;
        List<Integer> findIndexList;
        for (InfoPublish accept : acceptHelpList) {
            provideHelpList = getAllNunMatchRecords(CaliforniaSiteConstant.HelpType.PROVIDER);
            if (CollectionUtils.isEmpty(provideHelpList)) {
                logger.info("no providers");
                continue;
            }
            findIndexList = MatchingUtils.start(provideHelpList, accept.getAmount());
            matchInfoService.addRecord(findIndexList, provideHelpList, CaliforniaSiteConstant.HelpType.ACCEPT, accept);
        }

        provideHelpList = getAllNunMatchRecords(CaliforniaSiteConstant.HelpType.PROVIDER);
        for (InfoPublish provider : provideHelpList) {
            acceptHelpList = getAllNunMatchRecords(CaliforniaSiteConstant.HelpType.ACCEPT);
            if (CollectionUtils.isEmpty(acceptHelpList)) {
                logger.info("no accepter");
                continue;
            }
            findIndexList = MatchingUtils.start(acceptHelpList, provider.getAmount());
            matchInfoService.addRecord(findIndexList, provideHelpList, CaliforniaSiteConstant.HelpType.PROVIDER, provider);
        }
    }

    public void updateState(long id, int state, long updateTime) {
        InfoPublish publish = infoPublishMapper.selectByPrimaryKey(id);
        publish.setState(state);
        publish.setUpdateTime(updateTime);
        infoPublishMapper.updateByPrimaryKeySelective(publish);
    }

    public InfoPublish getById(long id) {
        return infoPublishMapper.selectByPrimaryKey(id);
    }

    public void freezeCheck() {
        InfoPublishExample example = new InfoPublishExample();
        example.createCriteria()
                .andHelpTypeEqualTo(CaliforniaSiteConstant.HelpType.PROVIDER)
                .andStateEqualTo(CaliforniaSiteConstant.InfoState.MATCHED);
        List<InfoPublish> publishList = infoPublishMapper.selectByExample(example);
        long now = System.currentTimeMillis();
        for (InfoPublish publish : publishList) {
            if (now - publish.getUpdateTime() > 24 * 3600 * 1000) { //超过24小时未打款
                californiaSiteUserService.freeAccount(publish.getAccountId());
                updateState(publish.getId(), CaliforniaSiteConstant.InfoState.FREEZE, now);
                logger.info("freeze account {} for play money time out.", publish.getAccountId());
            }
        }

        example = new InfoPublishExample();
        example.createCriteria()
                .andHelpTypeEqualTo(CaliforniaSiteConstant.HelpType.ACCEPT)
                .andStateEqualTo(CaliforniaSiteConstant.InfoState.WAIT_CONFIRM);
        publishList = infoPublishMapper.selectByExample(example);
        for (InfoPublish publish : publishList) {
            if (now - publish.getUpdateTime() > 24 * 3600 * 1000) { //超过24小时未确认
                californiaSiteUserService.freeAccount(publish.getAccountId());
                updateState(publish.getId(), CaliforniaSiteConstant.InfoState.FREEZE, now);
                logger.info("freeze account {} for confirm time out.", publish.getAccountId());
            }
        }
    }

    public List<String> getAccountIdById(List<Long> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            return Collections.emptyList();
        }
        InfoPublishExample example = new InfoPublishExample();
        example.createCriteria().andIdIn(idList);
        return infoPublishMapper.selectByExample(example).stream()
                .map(InfoPublish::getAccountId).collect(Collectors.toList());
    }
}
